namespace BM.Tools.WebControls.MForm.Navigation
{
    using System.Collections.Generic;

    /// <summary>
    /// The default implementation of the <see cref="INavigator{T}" /> interface, that uses the concept of locator.
    /// The locator is a class that provides filtering data.
    /// </summary>
    /// <typeparam name="T">
    /// The type of the navigable object.
    /// </typeparam>
    /// <typeparam name="TLocator">
    /// the type of the locator
    /// </typeparam>
    public abstract class Navigator<T, TLocator> : INavigator<T>
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="Navigator{T, TLocator}"/> class. 
        /// </summary>
        /// <param name="parent">
        /// The parent.
        /// </param>
        /// <param name="locator">
        /// The locator.
        /// </param>
        protected Navigator(INavigator<T> parent, TLocator locator)
        {
            Parent = parent;
            Locator = locator;
        }

        /// <summary>
        /// Gets or sets Locator.
        /// </summary>
        /// <value>
        /// The locator.
        /// </value>
        public TLocator Locator
        {
            get;
            set;
        }

        /// <summary>
        /// Gets Parent.
        /// </summary>
        /// <value>
        /// The parent.
        /// </value>
        public INavigator<T> Parent
        {
            get;
            private set;            
        }

        /// <summary>
        /// Provides the <see cref="NavigatorQuery{T}" /> object that can move through the tree.
        /// </summary>
        /// <param name="item">
        /// The item on which the query run.
        /// </param>
        /// <returns>
        /// the NavigatorQuery object
        /// </returns>
        public NavigatorQuery<T> Query(T item)
        {
            return Parent.Query(item);
        }

        /// <summary>
        /// performs the selection
        /// </summary>
        /// <returns>
        /// the enumerable of objects of type
        /// </returns>
        public abstract IEnumerable<T> Select();
    }
}